package xiaohongshu

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/binary"
	"errors"
	"fmt"
)

// MsgDecrypt 解密消息
type MsgDecrypt struct{}

// Decrypt 对密文进行解密
func (md *MsgDecrypt) Decrypt(text, encodingAesKey string) (string, error) {
	aesKey, err := base64.StdEncoding.DecodeString(encodingAesKey + "=")
	if err != nil {
		return "", err
	}

	block, err := aes.NewCipher(aesKey)
	if err != nil {
		return "", err
	}

	iv := aesKey[:16] // IV 是 AES 密钥的前 16 字节
	cipherText, err := base64.StdEncoding.DecodeString(text)
	if err != nil {
		return "", err
	}

	// 使用 CBC 模式解密
	mode := cipher.NewCBCDecrypter(block, iv)
	decrypted := make([]byte, len(cipherText))
	mode.CryptBlocks(decrypted, cipherText)

	// 去掉 PKCS7 填充
	decrypted, err = pkcs7Unpad(decrypted)
	if err != nil {
		return "", err
	}

	// 获取内容长度
	length := int(binary.BigEndian.Uint32(decrypted[16:20]))

	// 截取真实消息体
	msg := string(decrypted[20 : 20+length])
	return msg, nil
}

func Decrypt(text, encodingAesKey string) (string, error) {
	aesKey, err := base64.StdEncoding.DecodeString(encodingAesKey + "=")
	if err != nil {
		return "", err
	}

	block, err := aes.NewCipher(aesKey)
	if err != nil {
		return "", err
	}

	iv := aesKey[:16] // IV 是 AES 密钥的前 16 字节
	cipherText, err := base64.StdEncoding.DecodeString(text)
	if err != nil {
		return "", err
	}

	// 使用 CBC 模式解密
	mode := cipher.NewCBCDecrypter(block, iv)
	decrypted := make([]byte, len(cipherText))
	mode.CryptBlocks(decrypted, cipherText)

	// 去掉 PKCS7 填充
	decrypted, err = pkcs7Unpad(decrypted)
	if err != nil {
		return "", err
	}

	// 获取内容长度
	length := int(binary.BigEndian.Uint32(decrypted[16:20]))

	// 截取真实消息体
	msg := string(decrypted[20 : 20+length])
	return msg, nil
}

// pkcs7Unpad 删除解密后明文的补位字符
func pkcs7Unpad(decrypted []byte) ([]byte, error) {
	if len(decrypted) == 0 {
		return nil, errors.New("decrypted data is empty")
	}

	pad := decrypted[len(decrypted)-1]
	if int(pad) < 1 || int(pad) > aes.BlockSize {
		return nil, errors.New("invalid padding")
	}
	return decrypted[:len(decrypted)-int(pad)], nil
}

func test2() {
	md := &MsgDecrypt{}
	encryptedText := "your_encrypted_text"
	encodingAesKey := "your_encoding_aes_key"

	msg, err := md.Decrypt(encryptedText, encodingAesKey)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Decrypted Message:", msg)
	}
}
